﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Device.Location;
using Windows.Devices.Geolocation;
using Microsoft.Phone.Maps.Services;
using System.Xml;
using System.Xml.Linq;
using System.Net;
using IndustrialSmokeCalc.SmokeCalcWCF;
using Telerik.Windows.Controls;

namespace IndustrialSmokeCalc
{
    public class Location : INotifyPropertyChanged
    {
        private XElement locationXml;
        //public double Latitude { get; set; }
        //public double Longitude { get; set; }
        public string Address { get; set; }
        public string Street { get; set; }
        public string Village { get; set; }
        public string District { get; set; }
        public string City { get; set; }
        public string Province { get; set; }
        public string PostalCode { get; set; }

        public GeoCoordinate GetCoordinate()
        {            
            GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
            watcher.MovementThreshold = 1.0; // set to one meter
            watcher.TryStart(false, TimeSpan.FromMilliseconds(1000));
            double latitude = watcher.Position.Location.Latitude;
            double longitude = watcher.Position.Location.Longitude;
            return new GeoCoordinate(latitude, longitude);
        }

        public void GetAddress(string latitude, string longitude)
        {
            string requestUri = string.Format
                ("http://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&sensor=false&language=id", latitude.Replace(',', '.'), longitude.Replace(',', '.'));

            WebClient getAddress = new WebClient();
            getAddress.DownloadStringCompleted += GetAddressDownloadStringCompleted;
            getAddress.DownloadStringAsync(new Uri(requestUri));
        }

        private void GetAddressDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            //if (e.Error != null)
            {
                locationXml = XElement.Parse(e.Result);
                Street = ParseXml("route", "route");
                if (Street == "") Street = ParseXml("street_address", "route");
                Village = ParseXml("administrative_area_level_4", "administrative_area_level_4");
                District = ParseXml("administrative_area_level_4", "administrative_area_level_3");
                City = ParseXml("administrative_area_level_4", "administrative_area_level_2");
                Province = ParseXml("administrative_area_level_4", "administrative_area_level_1");
                PostalCode = ParseXml("postal_code", "postal_code");
                Address = String.Format("{0}, Desa {1}, Kecamatan {2}", Street, Village, District);
                NotifyPropertyChanged();
            }
        }

        private string ParseXml(string value1, string value2)
        {
            try
            {
                var result = locationXml.Elements("result").First(x => (string)x.Element("type") == value1);
                if (result != null)
                {
                    return result.Elements("address_component")
                        .Where(x => (string)x.Element("type") ==
                                    value2)
                        .Select(x =>
                        {
                            var element = x.Element("long_name");
                            return element != null ? element.Value : null;
                        })
                        .First();
                }
                return "";
            }
            catch (Exception)
            {
                return "";
            }
            
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
